#!/usr/bin/env python
# coding: utf-8

# In[25]:


import json
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

class Product:
    def __init__(self, id, name, price, oldprice, info, categoryid, defaultimg, state, isdelete, imgurl):
        self.id = id
        self.name = name
        self.price = price
        self.oldprice = oldprice
        self.info = info
        self.categoryid = categoryid
        self.defaultimg = defaultimg
        self.state = state
        self.isdelete = isdelete
        self.imgurl = imgurl

    def __repr__(self):
        return f"Product(id={self.id}, name={self.name}, price={self.price}, oldprice={self.oldprice}, info={self.info}, categoryid={self.categoryid}, defaultimg={self.defaultimg}, state={self.state}, isdelete={self.isdelete}, imgurl={self.imgurl})"

def load_data_from_json(json_data):
    """
    从 JSON 数据加载产品列表。
    """
    products = []
    for item in json_data:
        product = Product(
            id=item['id'],
            name=item['name'],
            price=item['price'],
            oldprice=item['oldprice'],
            info=item['info'],
            categoryid=item['categoryid'],
            defaultimg=item['defaultimg'],
            state=item['state'],
            isdelete=item['isdelete'],
            imgurl=item['imgurl']
        )
        products.append(product)
    return products

def recommend_products(user_products, all_products, top_n=8):
    """
    基于内容的推荐算法。
    :param user_products: 用户相关的产品列表（训练集）
    :param all_products: 所有产品列表（测试集）
    :param top_n: 每个用户产品推荐的数量
    :return: 推荐的产品列表
    """
    # 将用户产品和所有产品合并为一个列表
    combined_products = user_products + all_products

    # 提取产品描述信息
    product_descriptions = [product.info for product in combined_products]

    # 使用 TF-IDF 向量化产品描述
    tfidf = TfidfVectorizer(stop_words='english')
    tfidf_matrix = tfidf.fit_transform(product_descriptions)

    # 计算余弦相似度矩阵
    cosine_sim = cosine_similarity(tfidf_matrix, tfidf_matrix)

    # 推荐的产品集合
    recommended_products = set()

    # 遍历用户相关的产品，找到相似的产品
    for user_product in user_products:
        # 找到用户产品在 combined_products 中的索引
        user_product_index = combined_products.index(user_product)

        # 获取该产品的相似度评分
        sim_scores = list(enumerate(cosine_sim[user_product_index]))

        # 按相似度评分排序
        sim_scores = sorted(sim_scores, key=lambda x: x[1], reverse=True)

        # 获取前 top_n 个最相似的产品（排除自己）
        sim_scores = sim_scores[1:top_n + 1]

        # 获取这些产品的索引
        product_indices = [i[0] for i in sim_scores]

        # 将这些产品添加到推荐列表中
        for i in product_indices:
            recommended_product = combined_products[i]
            # 确保推荐的产品不在用户相关的产品中
            if recommended_product not in user_products:
                recommended_products.add(recommended_product)

    # 将推荐的产品转换为列表并返回
    return list(recommended_products)

def main():
    # 从文件中加载数据
    try:
        with open("user_products.json", "r", encoding="utf-8") as f:
            user_data = json.load(f)
            print("=== 加载的用户产品数据 ===")
            print(json.dumps(user_data, indent=2, ensure_ascii=False))
            user_products = load_data_from_json(user_data)
            
        with open("all_products.json", "r", encoding="utf-8") as f:
            all_data = json.load(f)
            print("\n=== 加载的所有产品数据 ===")
            print(json.dumps(all_data, indent=2, ensure_ascii=False))
            all_products = load_data_from_json(all_data)

        # 获取推荐产品
        recommended_products = recommend_products(user_products, all_products)

        # 打印推荐的产品
        print("\n=== 推荐的产品 ===")
        for product in recommended_products:
            print(product)

        # 将推荐的产品保存为 JSON 文件
        with open("recommendedproducts.json", "w", encoding="utf-8") as f:
            json.dump([product.__dict__ for product in recommended_products], f, indent=2, ensure_ascii=False)

        print("\n推荐的产品已保存到 recommendedproducts.json")

    except FileNotFoundError as e:
        print(f"错误：文件未找到 - {e}")
    except json.JSONDecodeError as e:
        print(f"错误：JSON 解析失败 - {e}")
    except Exception as e:
        print(f"发生未知错误：{e}")

if __name__ == "__main__":
    main()


# In[31]:





# In[ ]:





# In[ ]:




